home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / CBASE102.ARJ / CBIMP.C < prev    next >
Text File  |  1991-09-23  |  13KB  |  703 lines

  1. /*    Copyright (c) 1989 Citadel    */
  2. /*       All Rights Reserved        */
  3.  
  4. /* #ident    "@(#)cbimp.c    1.5 - 91/09/23" */
  5.  
  6. #include <ansi.h>
  7.  
  8. /* ansi headers */
  9. #include <ctype.h>
  10. #include <errno.h>
  11. #include <limits.h>
  12. #ifdef AC_STDDEF
  13. #include <stddef.h>
  14. #endif
  15. #include <stdio.h>
  16. #ifdef AC_STRING
  17. #include <string.h>
  18. #endif
  19.  
  20. /* local headers */
  21. #include "cbase_.h"
  22.  
  23. #ifndef isodigit
  24. #define isodigit(c)    (((c) >= '0' && (c) <= '7') ? 1 : 0)
  25. #endif
  26.  
  27. /*man---------------------------------------------------------------------------
  28. NAME
  29.      cbimp - import cbase data
  30.  
  31. SYNOPSIS
  32.  
  33. DESCRIPTION
  34.  
  35. SEE ALSO
  36.      cbcmp, cbexp.
  37.  
  38. DIAGNOSTICS
  39.      Upon successful completion, a value of 0 is returned.  Otherwise,
  40.      a value of -1 is returned, and errno set to indicate the error.
  41.  
  42. ------------------------------------------------------------------------------*/
  43. /* array data type import macro */
  44. #define vimp(IMPFCT) {                            \
  45.     int i = 0;                            \
  46.     int elems = n / sizeof(*cp);                    \
  47.                                     \
  48.     for (i = 0; i < elems; ++i) {                    \
  49.         if (IMPFCT(fp, cp, sizeof(*cp)) == -1) return -1;    \
  50.         ++cp;                            \
  51.     }                                \
  52.     return 0;                            \
  53. }
  54.  
  55. #define MAXFLDLEN    (1024)
  56. static char s[MAXFLDLEN + 1];
  57.  
  58. /* getfld:  get next field from import file */
  59. #ifdef AC_PROTO
  60. static int getfld(FILE *fp)
  61. #else
  62. static int getfld(fp)
  63. FILE *fp;
  64. #endif
  65. {
  66.     int i = 0;
  67.     int c = 0;
  68.  
  69.     memset(s, 0, sizeof(s));
  70.     for (i = 0; ; ++i) {
  71.         c = fgetc(fp);
  72.         if (ferror(fp)) {
  73.             CBEPRINT;
  74.             return -1;
  75.         }
  76.         if (feof(fp)) {
  77.             CBEPRINT;
  78.             return -1;
  79.         }
  80.         if (c == EXPFLDDLM || c == EXPRECDLM) {
  81.             break;
  82.         }
  83.         if (i >= sizeof(s) - 1) {
  84.             CBEPRINT;
  85.             return -1;
  86.         }
  87.         s[i] = c;
  88.     }
  89.     s[i] = NUL;
  90.  
  91.     return 0;
  92. }
  93.  
  94. /* t_char -> use t_uchar import function */
  95. #define charimp        ucharimp
  96.  
  97. /* t_charv -> use t_ucharv import function */
  98. #define charvimp    ucharvimp
  99.  
  100. /* ucharimp:  t_uchar import function */
  101. #ifdef AC_PROTO
  102. static int ucharimp(FILE *fp, void *p, size_t n)
  103. #else
  104. static int ucharimp(fp, p, n)
  105. FILE *fp;
  106. void *p;
  107. size_t n;
  108. #endif
  109. {
  110.     int c = 0;
  111.  
  112.     if (getfld(fp) == -1) {
  113.         return -1;
  114.     }
  115.     c = (unsigned char)s[0];
  116.     if (c == EXPESC) {
  117.         switch ((unsigned char)s[1]) {
  118.         case NUL:    /* premature end of field */
  119.             return -1;
  120.             break;    /* case NUL: */
  121. #ifdef AC_BELL
  122.         case 'a':    /* audible alert */
  123.             if (s[2] != NUL) return -1;
  124.             c = '\a';
  125.             break;    /* case 'a': */
  126. #endif
  127.         case 'b':    /* backspace */
  128.             if (s[2] != NUL) return -1;
  129.             c = '\b';
  130.             break;    /* case 'b': */
  131.         case 'f':    /* form feed */
  132.             if (s[2] != NUL) return -1;
  133.             c = '\f';
  134.             break;    /* case 'f': */
  135.         case 'n':    /* newline */
  136.             if (s[2] != NUL) return -1;
  137.             c = '\n';
  138.             break;    /* case 'n': */
  139.         case 'r':    /* carriage return */
  140.             if (s[2] != NUL) return -1;
  141.             c = '\r';
  142.             break;    /* case 'r': */
  143.         case 't':    /* horizontal tab */
  144.             if (s[2] != NUL) return -1;
  145.             c = '\t';
  146.             break;    /* case 't': */
  147.         case 'v':    /* vertical tab */
  148.             if (s[2] != NUL) return -1;
  149.             c = '\v';
  150.             break;    /* case 'v': */
  151.         default:    /* */
  152.             if (isodigit(s[1])) {
  153.                 if (!isodigit(s[2]) || !isodigit(s[3])) return -1;
  154.                 if (s[4] != NUL) return -1;
  155.                 if (sscanf(s + 1, "%3o", &c) != 1) return -1;
  156.             } else {
  157.                 if (s[2] != NUL) return -1;
  158.                 c = (unsigned char)s[1];
  159.             }
  160.             break;    /* default: */
  161.         }
  162.     }
  163.     *(unsigned char *)p = c;
  164.  
  165.     return 0;
  166. }
  167.  
  168. /* ucharvimp:  t_ucharv import function */
  169. #ifdef AC_PROTO
  170. static int ucharvimp(FILE *fp, void *p, size_t n)
  171. #else
  172. static int ucharvimp(fp, p, n)
  173. FILE *fp;
  174. void *p;
  175. size_t n;
  176. #endif
  177. {
  178.     unsigned char *cp = (unsigned char *)p;
  179.  
  180.     vimp(ucharimp);
  181. }
  182.  
  183. /* shortimp:  t_short import function */
  184. #ifdef AC_PROTO
  185. static int shortimp(FILE *fp, void *p, size_t n)
  186. #else
  187. static int shortimp(fp, p, n)
  188. FILE *fp;
  189. void *p;
  190. size_t n;
  191. #endif
  192. {
  193.     if (getfld(fp) == -1) {
  194.         return -1;
  195.     }
  196.     if (s[0] == NUL) {
  197.         *(short *)p = 0;
  198.     } else {
  199.         if (sscanf(s, "%hd", (short *)p) != 1) return -1;
  200.     }
  201.  
  202.     return 0;
  203. }
  204.  
  205. /* shortvimp:  t_shortv import function */
  206. #ifdef AC_PROTO
  207. static int shortvimp(FILE *fp, void *p, size_t n)
  208. #else
  209. static int shortvimp(fp, p, n)
  210. FILE *fp;
  211. void *p;
  212. size_t n;
  213. #endif
  214. {
  215.     signed short *cp = (signed short *)p;
  216.  
  217.     vimp(shortimp);
  218. }
  219.  
  220. /* ushortimp:  t_ushort import function */
  221. #ifdef AC_PROTO
  222. static int ushortimp(FILE *fp, void *p, size_t n)
  223. #else
  224. static int ushortimp(fp, p, n)
  225. FILE *fp;
  226. void *p;
  227. size_t n;
  228. #endif
  229. {
  230.     if (getfld(fp) == -1) {
  231.         return -1;
  232.     }
  233.     if (s[0] == NUL) {
  234.         *(unsigned short *)p = 0;
  235.     } else {
  236.         if (sscanf(s, "%hu", (unsigned short *)p) != 1) return -1;
  237.     }
  238.  
  239.     return 0;
  240. }
  241.  
  242. /* ushortvimp:  t_ushortv import function */
  243. #ifdef AC_PROTO
  244. static int ushortvimp(FILE *fp, void *p, size_t n)
  245. #else
  246. static int ushortvimp(fp, p, n)
  247. FILE *fp;
  248. void *p;
  249. size_t n;
  250. #endif
  251. {
  252.     unsigned short *cp = (unsigned short *)p;
  253.  
  254.     vimp(ushortimp);
  255. }
  256.  
  257. /* intimp:  t_int import function */
  258. #ifdef AC_PROTO
  259. static int intimp(FILE *fp, void *p, size_t n)
  260. #else
  261. static int intimp(fp, p, n)
  262. FILE *fp;
  263. void *p;
  264. size_t n;
  265. #endif
  266. {
  267.     if (getfld(fp) == -1) {
  268.         return -1;
  269.     }
  270.     if (s[0] == NUL) {
  271.         *(int *)p = 0;
  272.     } else {
  273.         if (sscanf(s, "%d", (int *)p) != 1) return -1;
  274.     }
  275.  
  276.     return 0;
  277. }
  278.  
  279. /* intvimp:  t_intv import function */
  280. #ifdef AC_PROTO
  281. static int intvimp(FILE *fp, void *p, size_t n)
  282. #else
  283. static int intvimp(fp, p, n)
  284. FILE *fp;
  285. void *p;
  286. size_t n;
  287. #endif
  288. {
  289.     signed int *cp = (signed int *)p;
  290.  
  291.     vimp(intimp);
  292. }
  293.  
  294. /* uintimp:  t_uint import function */
  295. #ifdef AC_PROTO
  296. static int uintimp(FILE *fp, void *p, size_t n)
  297. #else
  298. static int uintimp(fp, p, n)
  299. FILE *fp;
  300. void *p;
  301. size_t n;
  302. #endif
  303. {
  304.     if (getfld(fp) == -1) {
  305.         return -1;
  306.     }
  307.     if (s[0] == NUL) {
  308.         *(unsigned int *)p = 0;
  309.     } else {
  310.         if (sscanf(s, "%u", (unsigned int *)p) != 1) return -1;
  311.     }
  312.  
  313.     return 0;
  314. }
  315.  
  316. /* uintvimp:  t_uintv import function */
  317. #ifdef AC_PROTO
  318. static int uintvimp(FILE *fp, void *p, size_t n)
  319. #else
  320. static int uintvimp(fp, p, n)
  321. FILE *fp;
  322. void *p;
  323. size_t n;
  324. #endif
  325. {
  326.     unsigned int *cp = (unsigned int *)p;
  327.  
  328.     vimp(uintimp);
  329. }
  330.  
  331. /* longimp:  t_long import function */
  332. #ifdef AC_PROTO
  333. static int longimp(FILE *fp, void *p, size_t n)
  334. #else
  335. static int longimp(fp, p, n)
  336. FILE *fp;
  337. void *p;
  338. size_t n;
  339. #endif
  340. {
  341.     if (getfld(fp) == -1) {
  342.         return -1;
  343.     }
  344.     if (s[0] == NUL) {
  345.         *(long *)p = 0;
  346.     } else {
  347.         if (sscanf(s, "%ld", (long *)p) != 1) return -1;
  348.     }
  349.  
  350.     return 0;
  351. }
  352.  
  353. /* longvimp:  t_longv import function */
  354. #ifdef AC_PROTO
  355. static int longvimp(FILE *fp, void *p, size_t n)
  356. #else
  357. static int longvimp(fp, p, n)
  358. FILE *fp;
  359. void *p;
  360. size_t n;
  361. #endif
  362. {
  363.     signed long *cp = (signed long *)p;
  364.  
  365.     vimp(longimp);
  366. }
  367.  
  368. /* ulongimp:  t_ulong import function */
  369. #ifdef AC_PROTO
  370. static int ulongimp(FILE *fp, void *p, size_t n)
  371. #else
  372. static int ulongimp(fp, p, n)
  373. FILE *fp;
  374. void *p;
  375. size_t n;
  376. #endif
  377. {
  378.     if (getfld(fp) == -1) {
  379.         return -1;
  380.     }
  381.     if (s[0] == NUL) {
  382.         *(unsigned long *)p = 0;
  383.     } else {
  384.         if (sscanf(s, "%lu", (unsigned long *)p) != 1) return -1;
  385.     }
  386.  
  387.     return 0;
  388. }
  389.  
  390. /* ulongvimp:  t_ulongv import function */
  391. #ifdef AC_PROTO
  392. static int ulongvimp(FILE *fp, void *p, size_t n)
  393. #else
  394. static int ulongvimp(fp, p, n)
  395. FILE *fp;
  396. void *p;
  397. size_t n;
  398. #endif
  399. {
  400.     unsigned long *cp = (unsigned long *)p;
  401.  
  402.     vimp(ulongimp);
  403. }
  404.  
  405. /* floatimp:  t_float import function */
  406. #ifdef AC_PROTO
  407. static int floatimp(FILE *fp, void *p, size_t n)
  408. #else
  409. static int floatimp(fp, p, n)
  410. FILE *fp;
  411. void *p;
  412. size_t n;
  413. #endif
  414. {
  415.     if (getfld(fp) == -1) {
  416.         return -1;
  417.     }
  418.     if (s[0] == NUL) {
  419.         *(float *)p = 0;
  420.     } else {
  421.         if (sscanf(s, "%g", (float *)p) != 1) return -1;
  422.     }
  423.  
  424.     return 0;
  425. }
  426.  
  427. /* floatvimp:  t_floatv import function */
  428. #ifdef AC_PROTO
  429. static int floatvimp(FILE *fp, void *p, size_t n)
  430. #else
  431. static int floatvimp(fp, p, n)
  432. FILE *fp;
  433. void *p;
  434. size_t n;
  435. #endif
  436. {
  437.     float *cp = (float *)p;
  438.  
  439.     vimp(floatimp);
  440. }
  441.  
  442. /* dblimp:  t_ldouble import function */
  443. #ifdef AC_PROTO
  444. static int dblimp(FILE *fp, void *p, size_t n)
  445. #else
  446. static int dblimp(fp, p, n)
  447. FILE *fp;
  448. void *p;
  449. size_t n;
  450. #endif
  451. {
  452.     if (getfld(fp) == -1) {
  453.         return -1;
  454.     }
  455.     if (s[0] == NUL) {
  456.         *(double *)p = 0;
  457.     } else {
  458.         if (sscanf(s, "%lg", (double *)p) != 1) return -1;
  459.     }
  460.  
  461.     return 0;
  462. }
  463.  
  464. /* dblvimp:  t_doublev import function */
  465. #ifdef AC_PROTO
  466. static int dblvimp(FILE *fp, void *p, size_t n)
  467. #else
  468. static int dblvimp(fp, p, n)
  469. FILE *fp;
  470. void *p;
  471. size_t n;
  472. #endif
  473. {
  474.     double *cp = (double *)p;
  475.  
  476.     vimp(dblimp);
  477. }
  478.  
  479. /* ldblimp:  t_ldouble import function */
  480. #ifdef AC_PROTO
  481. static int ldblimp(FILE *fp, void *p, size_t n)
  482. #else
  483. static int ldblimp(fp, p, n)
  484. FILE *fp;
  485. void *p;
  486. size_t n;
  487. #endif
  488. {
  489.     if (getfld(fp) == -1) {
  490.         return -1;
  491.     }
  492. #ifdef AC_LDOUBLE
  493.     if (s[0] == NUL) {
  494.         *(long double *)p = 0;
  495.     } else {
  496.         if (sscanf(s, "%Lg", (long double *)p) != 1) return -1;
  497.     }
  498. #endif
  499.     return 0;
  500. }
  501.  
  502. /* ldblimp:  t_ldouble import function */
  503. #ifdef AC_PROTO
  504. static int ldblvimp(FILE *fp, void *p, size_t n)
  505. #else
  506. static int ldblvimp(fp, p, n)
  507. FILE *fp;
  508. void *p;
  509. size_t n;
  510. #endif
  511. {
  512. #ifdef AC_LDOUBLE
  513.     long double *cp = (long double *)p;
  514. #else
  515.     double *cp = (double *)p;
  516. #endif
  517.     vimp(ldblimp);
  518. }
  519.  
  520. /* ptrimp:  t_pointer import function */
  521. #ifdef AC_PROTO
  522. static int ptrimp(FILE *fp, void *p, size_t n)
  523. #else
  524. static int ptrimp(fp, p, n)
  525. FILE *fp;
  526. void *p;
  527. size_t n;
  528. #endif
  529. {
  530.     if (getfld(fp) == -1) {
  531.         return -1;
  532.     }
  533.     if (s[0] == NUL) {
  534.         *(void **)p = NULL;
  535.     } else {
  536.         if (sscanf(s, "%p", (void **)p) != 1) return -1;
  537.     }
  538.  
  539.     return 0;
  540. }
  541.  
  542. /* ptrvimp:  t_pointerv import function */
  543. #ifdef AC_PROTO
  544. static int ptrvimp(FILE *fp, void *p, size_t n)
  545. #else
  546. static int ptrvimp(fp, p, n)
  547. FILE *fp;
  548. void *p;
  549. size_t n;
  550. #endif
  551. {
  552.     void **cp = (void **)p;
  553.  
  554.     vimp(ptrimp);
  555. }
  556.  
  557. /* strimp:  t_string import function */
  558. #ifdef AC_PROTO
  559. static int strimp(FILE *fp, void *p, size_t n)
  560. #else
  561. static int strimp(fp, p, n)
  562. FILE *fp;
  563. void *p;
  564. size_t n;
  565. #endif
  566. {
  567.     unsigned char *si = NULL;
  568.     int i = 0;
  569.     int c = 0;
  570.  
  571.     if (getfld(fp) == -1) {
  572.         return -1;
  573.     }
  574.  
  575.     /* initialize return */
  576.     memset(p, 0, n);
  577.  
  578.     /* convert */ /* string will be truncated if too long */
  579.     si = (unsigned char *)s;
  580.     for (i = 0; i < n; ++i) {
  581.         c = *si++;
  582.         if (c == NUL) {
  583.             *((char *)p + i) = NUL;
  584.             break;
  585.         }
  586.         if (c == EXPESC) {
  587.             switch (*si) {
  588.             case NUL:    /* premature end of field */
  589.                 return -1;
  590.                 break;    /* case NUL: */
  591. #ifdef AC_BELL
  592.             case 'a':    /* audible alert */
  593.                 c = '\a';
  594.                 break;    /* case 'a': */
  595. #endif
  596.             case 'b':    /* backspace */
  597.                 c = '\b';
  598.                 break;    /* case 'b': */
  599.             case 'f':    /* form feed */
  600.                 c = '\f';
  601.                 break;    /* case 'f': */
  602.             case 'n':    /* newline */
  603.                 c = '\n';
  604.                 break;    /* case 'n': */
  605.             case 'r':    /* carriage return */
  606.                 c = '\r';
  607.                 break;    /* case 'r': */
  608.             case 't':    /* horizontal tab */
  609.                 c = '\t';
  610.                 break;    /* case 't': */
  611.             case 'v':    /* vertical tab */
  612.                 c = '\v';
  613.                 break;    /* case 'v': */
  614.             default:    /* */
  615.                 if (isodigit(*si)) {
  616.                     if (!isodigit(*(si + 1)) || !isodigit(*(si + 2))) return -1;
  617.                     if (sscanf(si, "%3o", &c) != 1) return -1;
  618.                     si += 2;
  619.                 } else {
  620.                     c = *si;
  621.                 }
  622.                 break;    /* default: */
  623.             }
  624.             ++si;
  625.         }
  626.         *((char *)p + i) = c;
  627.     }
  628.  
  629.     return 0;
  630. }
  631.  
  632. /* t_cistring -> use t_string import function */
  633. #define cistrimp    strimp
  634.  
  635. /* binimp:  t_binary import function */
  636. #ifdef AC_PROTO
  637. static int binimp(FILE *fp, void *p, size_t n)
  638. #else
  639. static int binimp(fp, p, n)
  640. FILE *fp;
  641. void *p;
  642. size_t n;
  643. #endif
  644. {
  645.     /* calculate number of hex digits for each char
  646.          # bits in char == CHAR_BIT, # bits in hex digit == 4 */
  647.     const int hexdigits = (CHAR_BIT + (4 - 1)) / 4;
  648.     unsigned char *si = (unsigned char *)s;
  649.     unsigned char *pi = (unsigned char *)p;
  650.     char fmt[24];            /* printf format string */
  651.     int c = 0;
  652.  
  653.     sprintf(fmt, "%%%dX", hexdigits);
  654.  
  655.     if (getfld(fp) == -1) {
  656.         return -1;
  657.     }
  658.  
  659.     /* initialize return */
  660.     memset(p, 0, n);
  661.  
  662.     for (;;) {
  663.         if (si - (unsigned char *)s >= sizeof(s) - hexdigits) break;
  664.         if (pi - (unsigned char *)p >= n) break;
  665.         if (sscanf(si, fmt, &c) != 1) return -1;
  666.         si += hexdigits;
  667.         *pi++ = (unsigned char)c;
  668.     }
  669.  
  670.     return 0;
  671. }
  672.  
  673. /* import function table definition */
  674. const cbimp_t cbimpv[] = {
  675.     charimp,        /* t_char    =  0 */
  676.     charvimp,        /* t_charv    =  1 */
  677.     ucharimp,        /* t_uchar    =  2 */
  678.     ucharvimp,        /* t_ucharv    =  3 */
  679.     shortimp,        /* t_short    =  4 */
  680.     shortvimp,        /* t_shortv    =  5 */
  681.     ushortimp,        /* t_ushort    =  6 */
  682.     ushortvimp,        /* t_ushortv    =  7 */
  683.     intimp,            /* t_int    =  8 */
  684.     intvimp,        /* t_intv    =  9 */
  685.     uintimp,        /* t_uint    = 10 */
  686.     uintvimp,        /* t_uintv    = 11 */
  687.     longimp,        /* t_long    = 12 */
  688.     longvimp,        /* t_longv    = 13 */
  689.     ulongimp,        /* t_ulong    = 14 */
  690.     ulongvimp,        /* t_ulongv    = 15 */
  691.     floatimp,        /* t_float    = 16 */
  692.     floatvimp,        /* t_floatv    = 17 */
  693.     dblimp,            /* t_double    = 18 */
  694.     dblvimp,        /* t_doublev    = 19 */
  695.     ldblimp,        /* t_ldouble    = 20 */
  696.     ldblvimp,        /* t_ldoublev    = 21 */
  697.     ptrimp,            /* t_pointer    = 22 */
  698.     ptrvimp,        /* t_pointerv    = 23 */
  699.     strimp,            /* t_string    = 24 */
  700.     cistrimp,        /* t_cistring    = 25 */
  701.     binimp,            /* t_binary    = 26 */
  702. };
  703.